﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Aga.Controls.Tree;
using System.IO;
using System.Reflection;

namespace UnrealDebugger.Panels
{
    public partial class CallstackPanel : Panel
    {
        public class CallstackNode : Node
        {
            public CallstackNode()
                : base()
            {
            }

            public CallstackNode(string text)
                : base(text)
            {
            }

            public int Position { get; set; }

            public Image Icon { get { return UnrealDebuggerIDE.Instance.ActiveCallstackPosition == this.Position ? _activeEntry : _inactiveEntry; } }

            private static Image _activeEntry = null;
            private static Image _inactiveEntry = null;

            static CallstackNode()
            {
                Stream file = null;
                Assembly assembly = typeof(CallstackNode).Assembly;

                file = assembly.GetManifestResourceStream("UnrealDebugger.Resources.ActiveCallstackEntry.png");
                _activeEntry = Image.FromStream(file);

                file = assembly.GetManifestResourceStream("UnrealDebugger.Resources.InactiveCallstackEntry.png");
                _inactiveEntry = Image.FromStream(file);
            }
        }

        private TreeModel _model = new TreeModel();

        public CallstackPanel()
            : base()
        {
            InitializeComponent();
            this.Load += new EventHandler(OnLoad);
            UnrealDebuggerIDE.Instance.OnDebuggerDetached += new UnrealDebuggerIDE.DebuggerDetachedDelegate(OnDebuggerDetached);
        }

        void OnDebuggerDetached()
        {
            this.treeViewCallstack.BeginUpdate();
            this._model.Nodes.Clear();
            this.treeViewCallstack.EndUpdate();
        }

        void OnLoad(object sender, EventArgs e)
        {
            this.treeViewCallstack.Model = _model;
        }

        #region Debugger Interface

        public void Clear()
        {
            this.treeViewCallstack.BeginUpdate();
            this._model.Nodes.Clear();
            this.treeViewCallstack.EndUpdate();
        }

        public void AddEntry(string entry)
        {
            this.treeViewCallstack.BeginUpdate();

            foreach (CallstackNode callstackNode in this._model.Nodes)
            {
                callstackNode.Position++;
            }

            CallstackNode node = new CallstackNode(entry);
            this._model.Nodes.Insert(0, node);

            this.treeViewCallstack.EndUpdate();
        }

        #endregion

        private void treeViewCallstack_DoubleClick(object sender, EventArgs e)
        {
            TreeNodeAdv node = this.treeViewCallstack.SelectedNode;
            CallstackNode entry = node != null ? node.Tag as CallstackNode : null;

            if (entry != null)
            {
                UnrealDebuggerIDE.Commands.ChangeStack(entry.Position);
            }
        }
    }
}
